package com.yixin.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yixin.hospital.common.ApiResult;
import com.yixin.hospital.common.BusinessException;
import com.yixin.hospital.entity.domain.*;
import com.yixin.hospital.entity.dto.req.visitInspection.AddVisitInspectionReqDTO;
import com.yixin.hospital.entity.vo.VisitInspectionListVO;
import com.yixin.hospital.enums.DrugVisitStatusEnum;
import com.yixin.hospital.enums.GuidanceStatusEnum;
import com.yixin.hospital.enums.InspectionOptStepEnum;
import com.yixin.hospital.enums.ResponseCodeEnum;
import com.yixin.hospital.mapper.VisitInspectionListMapper;
import com.yixin.hospital.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author Administrator
* @description 针对表【visit_inspection_list(检查项列表)】的数据库操作Service实现
* @createDate 2024-11-19 10:22:43
*/
@Service
public class VisitInspectionListServiceImpl extends ServiceImpl<VisitInspectionListMapper, VisitInspectionList>
    implements VisitInspectionListService{

    @Resource
    private VisitInspectionRealReportService visitInspectionRealReportService;
    @Resource
    private DrugService drugService;
    @Resource
    private GuidanceService guidanceService;
    @Autowired
    private VisitSubPackageDrugService visitSubPackageDrugService;
    @Autowired
    private VisitPackageDrugService visitPackageDrugService;


    @Override
    public ApiResult<?> addVisitInspection(AddVisitInspectionReqDTO addVisitInspectionReqDTO, String userName) {
        // 删除未缴费的检查
        this.remove(new LambdaQueryWrapper<VisitInspectionList>().eq(VisitInspectionList::getGuidanceCode, addVisitInspectionReqDTO.getGuidanceCode())
                .eq(VisitInspectionList::getStatus, DrugVisitStatusEnum.PENDING.getCode()));
        List<VisitInspectionList> newList = addVisitInspectionReqDTO.getVisitInspectionList().stream().filter(visitInspectionList -> visitInspectionList.getStatus() == 0).collect(Collectors.toList());
        for (VisitInspectionList visitInspectionList : newList) {
            visitInspectionList.setGuidanceCode(addVisitInspectionReqDTO.getGuidanceCode());
            visitInspectionList.setCreatedBy(userName);
            visitInspectionList.setUpdatedBy(userName);
        }
        if (!CollectionUtils.isEmpty(addVisitInspectionReqDTO.getVisitInspectionList())) {
            List<VisitInspectionList> pendingList = addVisitInspectionReqDTO.getVisitInspectionList().stream().filter(visitInspectionList -> visitInspectionList.getStatus() == DrugVisitStatusEnum.PENDING.getCode()).collect(Collectors.toList());
            this.saveBatch(pendingList);
        }
        // 重新存储计算金额
        visitInspectionRealReportService.remove(new LambdaQueryWrapper<VisitInspectionRealReport>()
                .eq(VisitInspectionRealReport::getGuidanceCode, addVisitInspectionReqDTO.getGuidanceCode()));
        for (VisitInspectionRealReport visitInspectionRealReport : addVisitInspectionReqDTO.getVisitInspectionRealReportList()) {
            visitInspectionRealReport.setGuidanceCode(addVisitInspectionReqDTO.getGuidanceCode());
            visitInspectionRealReport.setCreatedBy(userName);
            visitInspectionRealReport.setUpdatedBy(userName);
        }
        visitInspectionRealReportService.saveBatch(addVisitInspectionReqDTO.getVisitInspectionRealReportList());
        // 修改主记录状态
        Guidance guidance = guidanceService.getOne(new LambdaQueryWrapper<Guidance>().eq(Guidance::getGuidanceCode, addVisitInspectionReqDTO.getGuidanceCode()));
        guidance.setStatus(GuidanceStatusEnum.PAYING.getCode());
        guidanceService.updateById(guidance);
        return ApiResult.success();
    }

    @Override
    public ApiResult<?> getVisitInspectionDetail(String guidanceCode) {
        List<VisitInspectionListVO> list = new ArrayList<>();
        List<VisitInspectionList> visitInspectionLists = this.list(new LambdaQueryWrapper<VisitInspectionList>().eq(VisitInspectionList::getGuidanceCode, guidanceCode));
        for (VisitInspectionList visitInspectionList : visitInspectionLists) {
            // TODO for循环里 db，
            Drug drug = drugService.getOne(new LambdaQueryWrapper<Drug>().eq(Drug::getCode, visitInspectionList.getCode()));
            VisitInspectionListVO visitInspectionListVO = new VisitInspectionListVO();
            BeanUtils.copyProperties(visitInspectionList, visitInspectionListVO);
            visitInspectionListVO.setName(drug.getName());
            visitInspectionListVO.setOuterUnit(drug.getOuterUnit());
            visitInspectionListVO.setCommonName(drug.getCommonName());
            list.add(visitInspectionListVO);
        }

        return ApiResult.success(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResult<?> takeVisitInspection(AddVisitInspectionReqDTO addVisitInspectionReqDTO, String userName) {
        String guidanceCode = addVisitInspectionReqDTO.getGuidanceCode();
        Guidance guidance = guidanceService.getOne(new LambdaQueryWrapper<Guidance>().eq(Guidance::getGuidanceCode, guidanceCode));
        if (CollectionUtils.isEmpty(addVisitInspectionReqDTO.getVisitInspectionList())) throw new BusinessException(ResponseCodeEnum.INSPECTION_EMPTY_ERROR.getMsg());
        if (!guidance.getStatus().equals(GuidanceStatusEnum.CHECKING.getCode()) && !guidance.getStatus().equals(GuidanceStatusEnum.CHECKING_DRUG.getCode())) throw new BusinessException(ResponseCodeEnum.ILLEGAL_OPERATION.getMsg());
        // 检查
        List<VisitInspectionList> visitInspectionLists = this.list(new LambdaQueryWrapper<VisitInspectionList>().eq(VisitInspectionList::getGuidanceCode, guidanceCode));
        if(CollectionUtils.isEmpty(visitInspectionLists)) throw new BusinessException(ResponseCodeEnum.ILLEGAL_OPERATION.getMsg());
        for (VisitInspectionList inspectionList : visitInspectionLists) {
            List<Long> reqInspectionIds = addVisitInspectionReqDTO.getVisitInspectionList().stream().map(VisitInspectionList::getId).collect(Collectors.toList());
            if (reqInspectionIds.contains(inspectionList.getId())) {
                if (DrugVisitStatusEnum.PENDING.getCode() == inspectionList.getStatus()) throw new BusinessException(ResponseCodeEnum.INSPECTION_ERROR.getMsg());
                if (DrugVisitStatusEnum.DONE.getCode() == inspectionList.getStatus()) throw new BusinessException(ResponseCodeEnum.INSPECTION_EXIST.getMsg());
                inspectionList.setStatus(DrugVisitStatusEnum.DONE.getCode());
                inspectionList.setLastTime(LocalDateTime.now());
                inspectionList.setUpdatedBy(userName);
                inspectionList.setUpdatedTime(new Date());
            }
        }
        // 更新状态（减库存在开处方时已减）
        this.updateBatchById(visitInspectionLists);
        // 更新guidance表状态， 查处方是否有未取的药
        this.updateGuidanceStatus(guidance, visitInspectionLists, userName);
        return ApiResult.success();
    }

    @Override
    public void updateGuidanceStatus(Guidance guidance, List<VisitInspectionList> visitInspectionLists, String userName) {
        long subPackageDrugCount = visitSubPackageDrugService.count(new LambdaQueryWrapper<VisitSubPackageDrug>().eq(VisitSubPackageDrug::getGuidanceCode, guidance.getGuidanceCode()).eq(VisitSubPackageDrug::getStatus, DrugVisitStatusEnum.PAID.getCode()));
        long packageDrugCount = visitPackageDrugService.count(new LambdaQueryWrapper<VisitPackageDrug>().eq(VisitPackageDrug::getGuidanceCode, guidance.getGuidanceCode()).eq(VisitPackageDrug::getStatus, DrugVisitStatusEnum.PAID.getCode()));
        List<VisitInspectionList> availableInspectionList = visitInspectionLists.stream().filter(inspection -> inspection.getStatus().equals(DrugVisitStatusEnum.PAID.getCode())).collect(Collectors.toList());
        long visitingOptCount = availableInspectionList.stream().filter(inspection -> InspectionOptStepEnum.VISITING.getCode() == inspection.getOperationStep()).count();
        if (!CollectionUtils.isEmpty(availableInspectionList) && visitingOptCount > 0) {
            // 需要检查
            if (subPackageDrugCount != 0 || packageDrugCount != 0) {
                // 需要检查 && 需要取药
                guidance.setStatus(GuidanceStatusEnum.CHECKING_DRUG.getCode());
            } else {
                // 需要检查 && 不取药
                guidance.setStatus(GuidanceStatusEnum.CHECKING.getCode());
            }
        } else {
            // 已无检查
            if (subPackageDrugCount != 0 || packageDrugCount != 0) {
                // 无检查 && 需要取药
                guidance.setStatus(GuidanceStatusEnum.DRUG.getCode());
            } else {
                // 无检查 && 不取药 => 就诊完成
                guidance.setStatus(GuidanceStatusEnum.DONE.getCode());
                long afterVisitOptCount = availableInspectionList.stream().filter(inspection -> InspectionOptStepEnum.AFTER_VISIT.getCode() == inspection.getOperationStep()).count();
                if (afterVisitOptCount > 0) guidance.setStatus(GuidanceStatusEnum.CHECKING.getCode());
            }
        }
        guidance.setUpdatedBy(userName);
        guidance.setUpdatedTime(new Date());
        guidanceService.updateById(guidance);
    }

}




